/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package me.panpf.sketch.sample;

import me.panpf.sketch.materialdrawer.DrawerItem;
import me.panpf.sketch.materialdrawer.DrawerItemListener;
import me.panpf.sketch.materialdrawer.DrawerListener;
import me.panpf.sketch.materialdrawer.DrawerToolbarUI;
import me.panpf.sketch.sample.ui.BlockDisplayTestFraction;
import me.panpf.sketch.sample.widget.fraction.*;
import me.panpf.sketch.util.Utils;
import ohos.aafwk.ability.fraction.Fraction;
import ohos.aafwk.ability.fraction.FractionAbility;
import ohos.aafwk.ability.fraction.FractionScheduler;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.agp.utils.Color;
import ohos.agp.window.service.WindowManager;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.bundle.IBundleManager;
import ohos.multimodalinput.event.KeyEvent;
import ohos.multimodalinput.event.TouchEvent;
import ohos.security.SystemPermission;
import ohos.system.DeviceInfo;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * MainFractionAbility
 */
public class MainFractionAbility extends FractionAbility implements DrawerItemListener, DrawerListener {

    private static final int MENU_WIDTH = 755;
    private String[] mAllPermissions = new String[]{SystemPermission.READ_USER_STORAGE};
    private List<String> mNoPermissionList = new ArrayList<>();
    private Component mNullLayout;
    private SlideDrawer mDrawerLayout;
    private DrawerToolbarUI mDrawerToolbarUI;
    private DependentLayout mDependentDrawerLayout;
    private DirectionalLayout mMaskLayout;
    private DirectionalLayout mSectionsLayout;
    private List<DrawerItem> mSectionList;
    private DrawerItem mCurrentSection = null;
    private long mExitTime; // 退出的时间

    private StackLayout mMainFractionLayout;

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        WindowManager.getInstance().getTopWindow().get().setStatusBarColor(Color.TRANSPARENT.getValue());
        getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS);
        super.setUIContent(ResourceTable.Layout_ability_main);
        initComponent();
        initListener();
        initDrawerItem();

        initPermission();

        createParallelTaskDispatcher("", TaskPriority.DEFAULT);

        SampleSketchInitializer.initConfig(this);
    }

    private void initDrawerItem() {
        this.addDrawerItem(newDrawerItem("Samples", null, DrawerItem.MENU_HEADER));
        this.addDrawerItem(newDrawerItem("Photos", new PhotosFraction(), DrawerItem.MENU_ITEM));
        this.addDrawerItem(newDrawerItem("Unsplash", new UnsplashFraction(), DrawerItem.MENU_ITEM));
        this.addDrawerItem(newDrawerItem("Baidu GIF", new BaiduGifFraction(), DrawerItem.MENU_ITEM));
        this.addDrawerItem(newDrawerItem("Tenor GIF", new TenorGifFraction(), DrawerItem.MENU_ITEM));
        this.addDrawerItem(newDrawerItem("Apps", null, DrawerItem.MENU_DISABLE_ITEM));
        this.addDrawerItem(newDrawerItem("Apks", null, DrawerItem.MENU_DISABLE_ITEM));
        this.addDrawerItem(newDrawerItem("Settings", new SettingsFraction(), DrawerItem.MENU_ITEM));
        this.addDrawerItem(newDrawerItem("About", new AboutFraction(), DrawerItem.MENU_ITEM));

        this.addDrawerItem(newDrawerItem("Test", null, DrawerItem.MENU_HEADER));
        this.addDrawerItem(newDrawerItem("Huge Image Test", new BlockDisplayTestFraction(), DrawerItem.MENU_ITEM));
        this.addDrawerItem(newDrawerItem("Image Processor Test", new ImageProcessorTestFraction(), DrawerItem.MENU_ITEM));
        this.addDrawerItem(newDrawerItem("Image Shaper Test", new ImageShaperTestFraction(), DrawerItem.MENU_ITEM));
        this.addDrawerItem(newDrawerItem("Repeat Load Or Download Test", new RepeatLoadOrDownloadTestFraction(), DrawerItem.MENU_ITEM));
        this.addDrawerItem(newDrawerItem("inBitmap Test", new InBitmapTestFraction(), DrawerItem.MENU_ITEM));
        this.addDrawerItem(newDrawerItem("Image Orientation Test", new ImageOrientationTestFraction(), DrawerItem.MENU_ITEM));
        this.addDrawerItem(newDrawerItem("Base64 Image Test", new Base64ImageTestFraction(), DrawerItem.MENU_ITEM));
        this.addDrawerItem(newDrawerItem("Other Test", new OtherTestFraction(), DrawerItem.MENU_ITEM));
    }

    /**
     * addDrawerItem
     * @param section
     */
    public void addDrawerItem(DrawerItem section) {
        mSectionList.add(section);
        mSectionsLayout.addComponent(section.getView());
    }

    /**
     * newDrawerItem
     * @param title
     * @param fraction
     * @param menuType
     * @return DrawerItem
     */
    public DrawerItem newDrawerItem(String title, Fraction fraction, int menuType) {
        DrawerItem section = new DrawerItem(MainFractionAbility.this, title, fraction, menuType);
        section.setOnClickListener(this);
        return section;
    }

    private void initComponent() {
        mMainFractionLayout = (StackLayout) this.findComponentById(ResourceTable.Id_main_fraction);

        mMaskLayout = (DirectionalLayout) this.findComponentById(ResourceTable.Id_mask_layout);
        mMaskLayout.setAlpha(0f);

        mDrawerToolbarUI = (DrawerToolbarUI) findComponentById(ResourceTable.Id_drawerToolbarUI);
        mDrawerLayout = (SlideDrawer) this.findComponentById(ResourceTable.Id_drawer_layout);
        mDrawerLayout.setSlideEnabled(false);

        mDependentDrawerLayout = (DependentLayout) this.findComponentById(ResourceTable.Id_dependentDrawer_layout);
        mNullLayout = this.findComponentById(ResourceTable.Id_null_layout);

        mSectionsLayout = (DirectionalLayout) this.findComponentById(ResourceTable.Id_sections_layout);
        mSectionList = new LinkedList<>();

        int distance = 81;
        if (DeviceInfo.getModel().startsWith("ELS")) {
            distance = 140;
        } else if (DeviceInfo.getModel().startsWith("TAS")) {
            distance = 81;
        } else if (DeviceInfo.getModel().startsWith("ANA")) {
            distance = 122; // 128
        }
        ComponentContainer.LayoutConfig drawerParams = new SlideDrawer.LayoutConfig(MENU_WIDTH,
                Utils.getDisplayHeightInPx(MainFractionAbility.this) + distance, SlideDrawer.SlideDirection.START);
        mDependentDrawerLayout.setLayoutConfig(drawerParams);
    }

    private void initListener() {
        mNullLayout.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                mDrawerLayout.closeSmoothly();
            }
        });
        mNullLayout.setTouchEventListener(new Component.TouchEventListener() {
            @Override
            public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                if (mDrawerLayout.getSlideState() != SlideDrawer.DrawerState.CLOSE) {
                    return true;
                }
                return false;
            }
        });

        mDrawerLayout.addSlideListener(new SlideDrawer.SlideListener() {
            @Override
            public void onOpen(SlideDrawer slideDrawer, SlideDrawer.SlideDirection slideDirection) {
                onDrawerOpened(slideDrawer);
            }

            @Override
            public void onMiddle(SlideDrawer slideDrawer, SlideDrawer.SlideDirection slideDirection, SlideDrawer.DrawerState drawerState) {
                if (mMainFractionLayout.isEnabled()) {
                    mMainFractionLayout.setEnabled(false);
                }
            }

            @Override
            public void onClose(SlideDrawer slideDrawer, SlideDrawer.SlideDirection slideDirection) {
                onDrawerClosed(slideDrawer);
            }

            @Override
            public void onSlideChange(SlideDrawer slideDrawer, SlideDrawer.SlideDirection slideDirection, int i0, int i1) {
                if (mMainFractionLayout.isEnabled()) {
                    mMainFractionLayout.setEnabled(false);
                }
                if (null != mMaskLayout) {
                    Double alpth = 0.4 * slideDrawer.getSlideDistanceRatio();
                    mMaskLayout.setAlpha(alpth.floatValue());
                }
            }
        });
        mDrawerToolbarUI.setToolbarListener(new DrawerToolbarUI.ToolbarListener() {
            @Override
            public void onClickIcon() {
                mDrawerLayout.openSmoothly();
            }
        });
    }

    private void initPermission() {
        mNoPermissionList.clear();
        for (int i = 0; i < mAllPermissions.length; i++) {
            if (verifySelfPermission(mAllPermissions[i]) !=
                    IBundleManager.PERMISSION_GRANTED) {
                mNoPermissionList.add(mAllPermissions[i]);
            }
        }
        // 申请权限
        if (mNoPermissionList.size() > 0) {
            requestPermissionsFromUser(mNoPermissionList.toArray(new String[mNoPermissionList.size()]), 1000);
        } else {
            onClick(mSectionList.get(1));
        }
    }

    @Override
    public void onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults) {
        boolean hasPermissionDeny = false;
        if (requestCode == 1000) {
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] == -1) {
                    hasPermissionDeny = true;
                    break;
                }
            }
        }

        if (hasPermissionDeny) { // 如果有没有被允许的权限
            finish();
        } else {
            onClick(mSectionList.get(1));
        }
    }

    private void finish() {
        TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
        globalTaskDispatcher.delayDispatch(new Runnable() {
            @Override
            public void run() {
                terminateAbility();
            }
        }, 2000);
    }

    @Override
    protected void onActive() {
        super.onActive();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
        if (keyCode == KeyEvent.KEY_BACK) {
            exit();
            return true;
        }
        return super.onKeyDown(keyCode, keyEvent);
    }

    /**
     * exit
     */
    public void exit() {
        if ((System.currentTimeMillis() - mExitTime) > 2000) {
            Utils.toast(MainFractionAbility.this, "Click again to exit");
            mExitTime = System.currentTimeMillis();
        } else {
            terminateAbility();
        }
    }

    @Override
    public void onClick(DrawerItem section) {
        if (section == mCurrentSection) {
            mDrawerLayout.closeSmoothly();
            return;
        }

        syncSectionsState(section);
        mDrawerLayout.closeSmoothly();
    }

    private void syncSectionsState(DrawerItem section) {
        mCurrentSection = section;
        mDrawerToolbarUI.setTitle(mCurrentSection.getTitle());
        FractionScheduler fractionScheduler = getFractionManager().startFractionScheduler();
        fractionScheduler.replace(ResourceTable.Id_main_fraction, mCurrentSection.getFraction())
                .submit();
    }

    @Override
    public void onDrawerClosed(Component view) {
        view.getContext().getUITaskDispatcher().asyncDispatch(new Runnable() {
            @Override
            public void run() {
                mMainFractionLayout.setEnabled(true);
                mNullLayout.setClickable(false);
            }
        });
    }

    @Override
    public void onDrawerOpened(Component drawerView) {
        drawerView.getContext().getUITaskDispatcher().asyncDispatch(new Runnable() {
            @Override
            public void run() {
                mMainFractionLayout.setEnabled(false);
                mNullLayout.setClickable(true);
            }
        });
    }

}
